Java8ではラムダ式とストリームAPIが追加されたほか、いくつか便利になった機能がある。今回はそんな便利機能についてみていく。
■ 文字列連結関数の導入(String.Join関数)
文字列連結のクラスとしてStringJoinerクラスが追加されている。また、コレクションの要素を結合できるString.join関数も追加されている。ちなみに、文字列分割はいままでどおりString.split関数が利用できる。
◇サンプルコード
package application;
import java.util.ArrayList;
import java.util.StringJoiner;
public class TestString {
public static void main(String[] args)
{
// 一時変数
String str = null;
// 連結用クラスでjoin
StringJoiner sj = new StringJoiner( "," , "(" , ")" );
sj.add( "1st" );
sj.add( "2nd" );
sj.add( "3rd" );
str = sj.toString();
System.out.println( str );
// コレクションの要素をjoin
ArrayList list = new ArrayList();
list.add( "first" );
list.add( "second" );
list.add( "third" );
str = String.join( "," , list );
System.out.println( str );
}
}
◇実行結果
(1st,2nd,3rd)
first,second,third
■ メソッド参照
Java8から導入されたラムダ式は『便利だが可読性がちょっと…』という場合に、使えそうなのがメソッド参照。C言語で言うところの関数ポインタのようなもので、関数(メソッド)への参照を変数に代入したり、引数に渡すことができる。
例えばソート用の関数が複数行にわたる場合など、ラムダ式では見にくくなるコードも、関数として別の場所に記述してしまえば、可読性を損なうこともない。以下にメソッド参照を利用したソート処理(降順)のサンプルコードを示す。
◇サンプルコード
package application;
import java.util.ArrayList;
import java.util.Collections;
public class TestLambda {
public static void main(String[] args)
{
// ランダムな数字のリストを作成
ArrayList<integer> list = new ArrayList<>();
list.add( 5 );
list.add( -77 );
list.add( 24 );
list.add( 3 );
list.add( 987 );
list.add( 56 );
list.add( -9 );
list.add( 0 );
// 整列前のリストを出力
System.out.println("ソート前:");
for ( int i : list){ System.out.println(i); }
// 降順に整列
Collections.sort( list , TestLambda::compare );
// 上記コードをラムダ式で記述した場合↓
// Collections.sort( list , ( arg1 , arg2 ) -> arg2 - arg1 );
// 整列後のリストを出力
System.out.println();
System.out.println("ソート後:");
for ( int i : list){ System.out.println(i); }
}
/**
* ソート時の大小関係の比較用関数
* @param arg1
* @param arg2
* @return 『arg1がarg2より後である場合には正』『arg1がarg2よりも前である場合は負』『arg1とarg2は順不同である場合は0』の値を返す
*/
public static int compare( Integer arg1 , Integer arg2 )
{
return arg2 - arg1;
}
}
◇実行結果
ソート前:
5
-77
24
3
987
56
-9
0
ソート後:
987
56
24
5
3
0
-9
-77
■ 型推論の強化
Java 8 では型推論が強化されていて、明示的に記述しなくても型が分かる場合には記述が省略できるようになった。実は『メソッド参照』(上記)のコード(11行目の右辺)でも利用しており、『左辺値がArrayList<Integer>型だから、右辺値もArrayList<Integer>型である』ことをJavaコンパイラが判断している。そのため右辺値の『<>』の中の『Integer』という記述がなくてもコンパイル・エラーにならない。コーディング規約などがある場合には取り扱いに注意が必要となると思われる。
■ Base64の標準エンコーディング/デコーディング
Base64とは、簡単にいうと『英数字以外の文字を、英数字で表現する方法』のこと。本来、メールの本文には英数字しか使うことができないのだが、実際には日本語が利用可能である。これは送信側で英数字に変換(Base64エンコーディング)して送信、受信側で日本語に変換(Base64でコーディング)して表示しているためである。 例えば『あ』という文字をBase64でエンコーディングすると『44GC』という文字になる。
よく似たエンコードとしてパーセント・エンコーディングがあり、こちらはwebブラウザのURLで日本語を扱う際に利用される。Base64とはまったく別のエンコード方式であるので、間違わないように注意が必要である。
以下にBase64エンコーディング/デコーディングのサンプルを示す。
◇サンプルコード
package application;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
public class TestBase64 {
public static void main(String[] args)
{
// 一時変数
String encodeStr = null;
String decodeStr = null;
// Base64エンコーダ/デコーダの利用・その1
// RFC 4648およびRFC 2045の表1に明記された「Base64アルファベット」
Encoder baseEncoder = Base64.getEncoder();
Decoder baseDecoder = Base64.getDecoder();
encodeStr = baseEncoder.encodeToString( "あいうえお".getBytes() );
decodeStr = new String( baseDecoder.decode( encodeStr ) );
System.out.println("base64 エンコード前:" + encodeStr );
System.out.println("base64 デコード後 :" + decodeStr );
System.out.println();
// Base64エンコーダ/デコーダの利用・その2
// RFC 4648の表2に明記された「URLおよびファイル名で安全なBase64アルファベット」
Encoder mimeEncoder = Base64.getMimeEncoder();
Decoder mimeDecoder = Base64.getMimeDecoder();
encodeStr = mimeEncoder.encodeToString( "あいうえお".getBytes() );
decodeStr = new String( mimeDecoder.decode( encodeStr ) );
System.out.println("mime base64 エンコード前:" + encodeStr );
System.out.println("mime base64 デコード後 :" + decodeStr );
System.out.println();
// Base64エンコーダ/デコーダの利用・その3
// RFC 2045の表1に明記された「Base64アルファベット」
Encoder urlEncoder = Base64.getUrlEncoder();
Decoder urlDecoder = Base64.getUrlDecoder();
encodeStr = urlEncoder.encodeToString( "あいうえお".getBytes() );
decodeStr = new String( urlDecoder.decode( encodeStr ) );
System.out.println("url base64 エンコード前:" + encodeStr );
System.out.println("url base64 デコード後 :" + decodeStr );
System.out.println();
// URLエンコーダ/デコーダの利用
// webブラウザのurlとして利用できるエンコード方式
// Base64とは異なるエンコードであることが分かる
try {
// パーセント・エンコードで出力
encodeStr = URLEncoder.encode( "あいうえお" , "UTF-8" );
decodeStr = URLDecoder.decode( encodeStr , "UTF-8" );
System.out.println("パーセント・エンコード前:" + encodeStr );
System.out.println("パーセント・デコード後 :" + decodeStr );
} catch (UnsupportedEncodingException e) {
// 例外を出力
e.printStackTrace();
}
}
}
◇実行結果
base64 エンコード前:44GC44GE44GG44GI44GK
base64 デコード後 :あいうえお
mime base64 エンコード前:44GC44GE44GG44GI44GK
mime base64 デコード後 :あいうえお
url base64 エンコード前:44GC44GE44GG44GI44GK
url base64 デコード後 :あいうえお
パーセント・エンコード前:%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A
パーセント・デコード後 :あいうえお
■ 参照
- JDK 8の新機能
- JavaDoc - クラスStringJoiner
- JavaDoc - クラスBase64